跳到主要内容

2.4-错误捕获及兼容

Create by fall on 23 Nov 2021 Recently revised in 07 Apr 2023

调试错误的方法

可以通过 F12 打开调试窗口进行调试

anonymous 表示匿名的

控制台

console

console 用于在控制台打印内容

console.time('test1');
console.timeEnd('test1');
//通过以上的方法,进行时间的计算
console.log('log') // 打印日志
console.info("what is going on")
console.warn("It's a warning")
console.error('one Error') // 打印错误

打印的其它用法

const obj = {nana:'fall',fun:'foo'}
// 以两个空格为缩进,输出对象
console.log(JSON.stringify(obj,null,2))
var a = "background: rgb(248, 177, 173);color: rgb(63, 172, 203)";
console.log("%c Jazz.Computer ", a)
console.log("%c 2015 ", a)
console.log("%c Yotam Mann ", a)
console.log("%c Sarah Rothberg ", a)

对于有特殊效果的内容,更推荐 console.info

console.info(
  `%c FanTable %c 0.2.1  %c @Powered by Fall-Zhang `,
  'padding: 2px 1px; border-radius: 3px 0 0 3px; color: #fff; background: #4b25ba; font-weight: bold;',
  'padding: 2px 1px; border-radius: 0 3px 3px 0; color: #fff; background: #a88dea; font-weight: bold;',
  'padding: 2px 1px; border-radius: 0 3px 3px 0; color: #fff; background: black; font-weight: bold;',
);
// 可以输出 base64 的图片
console.info(
'%c %cAdobe %cPhotoshop Web%c %c2023.23.0.1%c %c037a8af9746',
'padding-left: 36px; line-height: 36px; background-image: url("data:image/gif;base64,R0lGODlhIAAgAPEBAAAAAP///wAAAAAAACH5BAEAAAIALAAAAAAgACAAAAKkhC+py3zfopxGvIsztsCGD4La2FVAGBoBuZnox45WcqLsum5KDWdvf1nwTo+fLbgDqo7LFCJJbOY0oidt6ozVKrtib0qaCnlYcJh7rf5iK6HZaM64VeS6L+pWf89WT+6vRAUBBVQ1gpOTJ4IYdxCnOBSJ8ZhkZNekk5ZSxpTpt6Y1eEVm00j3VALDmBXVyPEJB2r2ShoLh2ASqvU60dsr5yuBUQAAOw=="); background-size: 32px; background-repeat: no-repeat; background-position: 2px 2px',
'background: #666; border-radius:0.5em 0 0 0.5em; padding:0.2em 0em 0.1em 0.5em; color: white; font-weight: bold',
'background: #666; border-radius:0 0.5em 0.5em 0; padding:0.2em 0.5em 0.1em 0em; color: white;',
'',
'background: #c3a650; border-radius:0.5em; padding:0.2em 0.5em 0.1em 0.5em; color: white;',
'',
'background: #15889f; border-radius:0.5em; padding:0.2em 0.5em 0.1em 0.5em; color: white;'
);
// 输出 svg,并且有渐变效果
console.info(
'%c ',
`padding-left:750px;padding-top:200px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 750 200'%3E%3Cstyle%3E text %7B font-family: sans-serif; font-weight: 100; fill: %23d8eaff; %7D %23stop1 %7B animation: recolor 40s linear infinite alternate %7D %23stop2 %7B animation: recolor 40s -32s linear infinite alternate %7D @keyframes recolor %7B 0%25 %7B stop-color: %23388bee; %7D 20%25 %7B stop-color: %2324c6dc; %7D 40%25 %7B stop-color: %23af74fd; %7D 60%25 %7B stop-color: %23c020d9; %7D 80%25 %7B stop-color: %23514a9d; %7D 100%25 %7B stop-color: %23053ece; %7D %7D %3C/style%3E%3Cdefs%3E%3ClinearGradient id='grad'%3E%3Cstop id='stop1' offset='0%25' stop-color='%23388bee'%3E%3C/stop%3E%3Cstop id='stop2' offset='100%25' stop-color='%23514a9d'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='750' height='500' fill='url(%23grad)'%3E%3C/rect%3E%3Ctext text-anchor='end' font-size='50' x='725' y='125'%3E thanks for %3C/text%3E%3Ctext text-anchor='end' font-size='50' x='725' y='175'%3E stopping by %3C/text%3E%3C/svg%3E")`
);

Error

new Error('你的年龄太小了,看不得')
// Error: 你的年龄太小了,看不得
// <anonymous> debugger eval code:1
new TypeError('类型错误!')

这些内置的错误信息都继承自 Error

  • RangeError:数字类型变量,或者参数超出有效范围时
  • ReferenceError:引用出现错误时抛出该错误
  • SyntaxError:解析无效 JavaScript 代码是,会出现该错误
  • TypeError:变量或者是参数不是有效的类型时
  • URIError:传入无效的参数至 encodeURI()decodeURI()
'use strict';
console.log.apply(console, new Array(1000000000)); // RangeError: 数组长度无效
console.log(notValidVar); // ReferenceError: notValidVar 未定义
1 *** 3 // SyntaxError: 无效的标记 *
'1.2'.toPrecision(1) // TypeError: '1.2'.toPrecision 不是函数
// 传入无效的参数至 `encodeURI()` 和 `decodeURI()` 时,会出现 `URIError` 的错误提示:
decodeURI('%') // URIError: URL 异常

Error Cause

如果自定义抛出错误,会导致原本的错误内容消失,因此添加 cause 后,可以保留浏览器抛出的错误

try {
maybeWorks();
} catch (err) {
throw new Error('maybeWorks failed!', { cause: err });
}

throw

let a = '你太小了'
throw a
// Uncaught 你太小了
throw new Error('请勿靠近!')

尽量抛出,或者是返回 Error 对象,或者是继承 Error 对象的其他错误对象,以便于调试

try & catch

在传输过程中可能出现错误,应用在ajax的兼容和新添加代码块时,可以使用,避免错误影响过大

执行过程

  • 先执行try中的代码
  • try中代码正常,不执行catch中的代码
  • try中代码出现错误,直接执行catch中的代码进行补救
try{
// 尝试执行
}catch(error){
// error 错误对象,try括号中代码执行的异常信息
}

相比于 if else 判断, try catch 效率更高,更加适合执行流程

try_throw_catch

throw 抛出异常

try{
alert("这里有个错误");
throw new Error("别紧张,只是演习");
alert("怎么会来到了错误后面");
}catch(error){
alert("补救代码,"+error)
}

debugger

相当于一个断点,程序执行到 debugger 的时候会暂停

// 当在某一点的时候,如果你不想要执行,可以直接使用 debugger 进行调试

debugger

finally

在 Promise 中进行使用,无论请求成功或者失败,都会执行的内容

axios.get('https://www.baidu.com').then(res=>{
// do something
}).catch(res=>{
// do something handle the error
}).finally(()=>{
// the thing always do after quest
})

更好地捕获错误

为了确保下一个开发者能够看懂,需要避免

// 同时捕获两个函数,可能不清楚哪个函数会抛出异常
try{
const foo = task()
const bar = task()
}catch(e){
console.log('Error: ',e)
}

改进:为每一个可能抛出异常的代码进行显示捕获

try {
const foo = runTask1();
} catch (e) {
console.log('Error:', e);
}

try {
const bar = runTask2();
} catch (e) {
console.log('Error:', e);
}

浏览器兼容

可在该文章内查看浏览器兼容的详情:浏览器的兼容问题及解决方案整理(建议收藏)

现如今,IE 浏览器已经停止维护,大多数现代浏览器 API 都遵从 ES6 开发规范,作为开发者,尽量避免使用规范以外的内容,即可减少不必要的兼容。

判断是什么浏览器

如何获取是使用的那个浏览器?

navigator.userAgent 能够判断是那种浏览器。比如说:

// qq 浏览器的 userAgent
mozilla/5.0 (iphone; cpu iphone os 11_1_2 like mac os x) applewebkit/604.3.5 (khtml, like gecko) mobile/15b202 qq/7.5.8.422 v1_iph_sq_7.5.8_1_app_a pixel/1080 core/uiwebview device/apple(iphone 8plus) nettype/wifi qbwebviewtype/1
// 微信内置浏览器
mozilla/5.0 (iphone; cpu iphone os 11_1_2 like mac os x) applewebkit/604.3.5 (khtml, like gecko) mobile/15b202 micromessenger/6.6.6 nettype/wifi language/zh_cn

使用浏览器 userAgent 中独有的数据段来确保浏览器的类型

let agent = navigator.userAgent.toLowerCase()
const isQQBrowser = agent.includes('15b202 qq') // 为 true 则表明是 qq 浏览器
const isWechat = agent.includes('15b202 micromessenger')

插件兼容

更多详情可以查看[【前端开发工具】](../npm 包/babel.md)章节

在实际项目中,通过两个组件实现向下兼容。

babel 作用于语法,实现新的语法兼容。

core.js 作用于 API,比如说 Fetch 或者是 Proxy 等 API 的实现。

参考文章

作者链接
OBKoro1https://juejin.cn/post/6844903602591383565